
package com.niguang.work.show.common.jackson;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * Created by yangwei on 2017/7/4.
 */
public class WebJsonSerializer extends JsonSerializer<Object> {

    private static final ConcurrentMap<JavaType, WebJsonSerializer> map = new ConcurrentHashMap<>();
    private JavaType clazz;

    private WebJsonSerializer(JavaType clazz) {
        this.clazz = clazz;
    }

    public static WebJsonSerializer getSingleton(JavaType type) {
        WebJsonSerializer ob = map.get(type);

        if (ob == null) {
            synchronized (map) {
                ob = new WebJsonSerializer(type);
                map.put(type, ob);
            }
        }

        return ob;
    }

    @Override
    public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        if (clazz.isTypeOrSubTypeOf(String.class) || clazz.isTypeOrSubTypeOf(Date.class)
                || clazz.isTypeOrSubTypeOf(LocalDateTime.class) || clazz.isTypeOrSubTypeOf(LocalDate.class)) {
            gen.writeString("");// String和时间处理为""
        } else if (clazz.isArrayType() || clazz.isTypeOrSubTypeOf(List.class) || clazz.isTypeOrSubTypeOf(Set.class)) {
            // 数组，list，set 处理为[]
            gen.writeStartArray();
            gen.writeEndArray();
        } else if (clazz.isTypeOrSubTypeOf(Number.class)) {
            gen.writeNumber(0);// 数字类型处理为0
        } else if (clazz.isTypeOrSubTypeOf(Boolean.class)) {
            gen.writeBoolean(false);// Boolean处理为false
        } else {
            // 其他空对象处理为 {}
            gen.writeStartObject();
            gen.writeEndObject();
        }
    }

}
